package com.xiaodou.mjf.web.xface.product.controller;

import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.xiaodou.mjf.application.core.manager.AccountManager;
import com.xiaodou.mjf.application.core.service.AccountService;
import com.xiaodou.mjf.application.core.service.BankCardCashioService;
import com.xiaodou.mjf.application.core.service.DepositService;
import com.xiaodou.mjf.application.core.service.FinancingService;
import com.xiaodou.mjf.application.core.service.FinancingStatisticsService;
import com.xiaodou.mjf.application.core.service.InvestService;
import com.xiaodou.mjf.application.core.service.OrderService;
import com.xiaodou.mjf.application.fee.manager.FeeManager;
import com.xiaodou.mjf.application.user.service.MemberSecurityService;
import com.xiaodou.mjf.application.user.service.MemberService;
import com.xiaodou.mjf.application.user.utils.MemberUtils;
import com.xiaodou.mjf.entity.core.Account;
import com.xiaodou.mjf.entity.core.Financing;
import com.xiaodou.mjf.entity.core.Invest;
import com.xiaodou.mjf.entity.core.NotesBook;
import com.xiaodou.mjf.entity.core.Order;
import com.xiaodou.mjf.entity.user.MemberSecurity;
import com.xiaodou.mjf.infrastructure.common.controller.ApiController;
import com.xiaodou.mjf.infrastructure.common.utils.Encrypt;
import com.xiaodou.mjf.infrastructure.common.utils.StringUtils;
import com.xiaodou.mjf.infrastructure.payment.RZContents;
import com.xiaodou.mjf.web.xface.common.ResultCode;
import com.xiaodou.mjf.web.xface.core.utils.TradeCode;

/**
 * Created by Rocky on 2/27/15.
 */
@RestController
@RequestMapping("v1/order")
public class OrderController extends ApiController {

	@Resource
	MemberSecurityService memberSecurityService;
	@Resource
	MemberService memberService;
	@Resource
	FinancingStatisticsService financingStatisticsService;
	@Resource
	InvestService investService;
	@Resource
	AccountService accountService;
	@Resource
	FinancingService financingService;
//	@Resource
//	NotesBookService notesBookService;
	@Resource
	DepositService depositService;
    @Resource
    OrderService orderService;
    @Resource
    AccountManager accountManager;
	@Resource
	FeeManager feeManager;	
	@Resource
	BankCardCashioService bankCardCashioService;
	
	public static final String PAYMENT_CHANNEL_MEIFUBAO = "1";
	public static final String PAYMENT_CHANNEL_ALIPAY = "2";
	public static final String PAYMENT_CHANNEL_WECHAT = "3";

	public static final String PAYMENT_METHOD_BALANCE = "1";
	public static final String PAYMENT_METHOD_BANKCARD = "2";

	/**
	 * 查询订单详情
	 * 
	 * @param tn 对应invest表中的id
	 */
	@RequestMapping("{tn}")
	public Map<String, Object> get(@PathVariable String tn) {
		Map<String,Object> result = success();
		
		Invest invest = investService.get(tn);
		if(invest==null){
			return failure(ResultCode.ORDER_RECORD_NOT_EXIST);
		}
		// 订单金额 order_amount
		result.put("order_amount", invest.getAmount());
		// 产品编号 id
		result.put("id", invest.getFinanceId());
		// 产品名称 name
		result.put("name", financingService.get(invest.getFinanceId())
					.getTitle());
		// 订单号 order_id
		result.put("order_id", tn);
		// 交易流水号 serial_number TODO
		result.put("serial_number", "");
		// 美付宝支付金额 payment_amount TODO
		result.put("payment_amount", "4980");
		// 优惠描述 privileges TODO
		result.put("privileges", "立减20");
		// 包名（Android） package TODO
		result.put("package_name", "");
		// Url Scheme（iOS） url_scheme TODO
		result.put("url_schema", "");

		return result;
	}
    /**
     * 确认支付
     * @param tn TN值
     * @param uid 客户编号
     * @param channel 支付渠道
     * @param method 支付方式
     * @param bankName 银行名称
     * @param cardNumber 银行卡号
     * @param tradePassword 交易密码
     * */
	@RequestMapping("{tn}/payment")
	public Map<String, Object> payment(
			@PathVariable String tn,
			@RequestHeader(required = false) String uid,
			String channel,
			String method,
			@RequestParam(value = "bank_name", required = false) String bankName,
			@RequestParam(value = "card_number", required = false) String cardNumber,
			@RequestParam(value = "trade_password", required = false) String tradePassword) {

		if (StringUtils.isBlank(uid)) {
			return failure(ResultCode.MISSING_UID_PARAM);
		}

		if (StringUtils.isBlank(channel) || StringUtils.isBlank(method)
				|| StringUtils.isBlank(tradePassword)) {
			return failure(ResultCode.MISSING_PARAMS);
		}

		if (method.equals(PAYMENT_METHOD_BANKCARD)
				&& (StringUtils.isBlank(cardNumber) || StringUtils
						.isBlank(bankName))) {
			return failure(ResultCode.MISSING_BANKCARD_PARAM);
		}

		Invest invest = new Invest();
		Account account = new Account();
		Financing financing = new Financing();
		
		// 验证交易密码是否正确
		try {
			MemberSecurity memberSecurity = memberSecurityService.get(uid);
			if (memberSecurity != null) {
				if (!Encrypt.validatePassword(
						memberSecurity.getTradePassword(), tradePassword)) {
					return failure(ResultCode.INVALID_PASSWORD);
				}
			}
			//01为美付宝，02为支付宝，03为微信
			if (PAYMENT_CHANNEL_MEIFUBAO.equals(channel)) {
				//01为余额支付，02为银行卡支付
				switch (method) {
				case PAYMENT_METHOD_BALANCE:
					// 通过tn号（订单号）查询financing_statistics表获取finance_id
					//financingStatistics = financingStatisticsService.get(tn);
                    invest = investService.get(tn);

					account = MemberUtils.getAccount(invest.getMemberId());

                    if(Double.compare(account.getAvaliableBalance(),invest.getAmount()) < 0){
                        return failure(ResultCode.INSUFFICIENT_BALANCE);
                    }

                    accountManager.transferOut(account, RZContents.CHANNEL_ID, invest.getAmount(), NotesBook.TYPE_INVEST, "投资");

					//根据查询financing获取type
					financing = financingService.get(invest.getFinanceId());

					//根据type判断是小豆还是美丽,如果是美丽产品，设置earnedProfit，美丽产品：已赚取收益=返现金额
					// add by David 2015/04/20 start
					invest.setEarnedProfit(invest.getExpectedProfit());
					// add by David 2015/04/20 end
					if(Financing.TYPE_MEILI.equals(financing.getType())) {
                        accountManager.grantVoucher(account,RZContents.CHANNEL_ID,invest.getExpectedProfit(),NotesBook.TYPE_VOUCHER,"现金立返");
//						invest.setEarnedProfit(invest.getExpectedProfit());
					}
//					else if(Financing.TYPE_XIAODOU.equals(financing.getType())) {						
//						invest.setExpectedProfit(invest.getAmount() * financing.getMinProfitRate() / 100 / 12 * financing.getTerm());
//					}
					//更新invest表记录（修改状态变为已支付）
					invest.setPaymentStatus(Invest.INVEST_PAYMENT);
					investService.save(invest);
					break;
				case PAYMENT_METHOD_BANKCARD:
					return failure("1020", "银行卡支付尚未开通");
					
				default:
					return failure("1016", "支付方式错误");
				}
			} else if (PAYMENT_CHANNEL_ALIPAY.equals(channel)) {
				return failure("1018", "支付宝支付尚未开通");
				//  支付宝支付
			} else if (PAYMENT_CHANNEL_WECHAT.equals(channel)) {
				return failure("1019", "微信支付尚未开通");
				//  微信支付
			} else {
				return failure("1015", "支付渠道错误");
			}
		} catch (Exception e) {
			logger.error(e.toString());
			return failure("1014", "确认支付失败");
		}

		Map<String,Object> result = success();
		return result;
	}


    @RequestMapping("notify_url")
    public String notify_(HttpServletRequest request){

        try {

            //订单号
            String orderId = request.getParameter("order_id");
            Double amount = Double.parseDouble(request.getParameter("amount"));
            String channelId = request.getParameter("channel_id");
//            String pay_time = request.getParameter("pay_time");
            String tradeCode = request.getParameter("trade_code");
            String code = request.getParameter("code");

            if(code.equals("0000")){
            
	            if (tradeCode.equals(TradeCode.DEPOSIT) && channelId.startsWith("1")) {
	
	                Order order = orderService.get(orderId);
	                Account account = MemberUtils.getAccountByMobile(order.getMobile());
	
	                accountManager.deposit(account, channelId, amount, NotesBook.TYPE_DEPOSIT, "充值", "30200001", orderId);
	
	                MemberUtils.setRealName(account.getMemberId());
	                //充值时 cashin累加 add by David 2015/04/15 start	                
	                MemberUtils.addCashIn(account.getMemberId(),order.getCardNumber(),amount);
	                //充值时 cashin累加 add by David 2015/04/15 end
	
	            } else if(tradeCode.equals(TradeCode.PAYMENT) && channelId.startsWith("1")){
	                Invest invest = investService.get(orderId);
	                if (invest == null) {
	                    return "failure";
	                }
	
	                Account account = MemberUtils.getAccount(invest.getMemberId());
	
	                accountManager.deposit(account, channelId, amount, NotesBook.TYPE_DEPOSIT, "充值", "30200001", orderId);
	                accountManager.transferOut(account, channelId, amount, NotesBook.TYPE_INVEST, "投资");
	                if(Financing.TYPE_MEILI.equals(invest.getType())) {
	                	accountManager.grantVoucher(account,channelId ,invest.getExpectedProfit(),NotesBook.TYPE_VOUCHER,"代金券发放");
	                }
	
	                invest.setStatus(Invest.INVEST_PAYMENT);
					invest.setPaymentStatus(Invest.INVEST_PAYMENT);
	
	                investService.save(invest);
	
	                MemberUtils.setRealName(account.getMemberId());
	
	            }else if(tradeCode.equals(TradeCode.REPAYMENT)){
	            	Order order = orderService.get(orderId);
	                if (order == null) {
	                    return "failure";
	                }
	    			//
	                Account account = MemberUtils.getAccountByMobile(order.getMobile());
	    			accountManager.transferOut(account, RZContents.CHANNEL_ID, amount, NotesBook.TYPE_REPAYMENT_PRINCIPLE, "还款");
					// order.getExtData(); 2015^8
					feeManager.payback(account.getMemberId(),Integer.parseInt(order.getExtData().substring(0,4)),Integer.parseInt(order.getExtData().substring(5, order.getExtData().length())), amount);

	            }
            }
        }catch(Exception e){
        	logger.error(e.toString());
            e.printStackTrace();
            return "failure";
        }

        return "success";
    }
	
}
